import Input from '@/components/Input'
import NavBar from '@/components/NavBar'
import Textarea from '@/components/Textarea'
import { useAppSelector } from '@/store'
import { clearAuth, editUserPhoto, editUserProfile, getUserProfile } from '@/store/action/user'
import { Profile } from '@/store/reducer/user'
import history from '@/utils/history'
import { removeTokenInfo } from '@/utils/storage'
import { DatePicker, Dialog, List, Popup, Toast } from 'antd-mobile'
import dayjs from 'dayjs'
import { useEffect, useRef, useState } from 'react'
import { useDispatch } from 'react-redux'
import styles from './index.module.scss'

// 定义底部弹出层类型，TS修改代码的时候有更好的提示和静态校验
type PopupBottom = {
  visible: boolean
  // string 类型范围太大，把类型收窄为 'photo' | 'gender' | ''
  type: 'photo' | 'gender' | ''
}

// 右侧弹出层类型
type PopupRight = {
  visible: boolean
  type: 'name' | 'intro' | ''
}

export default function ProfileEdit() {
  // 发送请求：获取用户个人资料
  const dispatch = useDispatch()
  useEffect(() => {
    dispatch(getUserProfile())
  }, [dispatch])

  const { profile } = useAppSelector((state) => state.user)

  // 底部弹出层显示状态
  const [popupBottom, setPopupBottom] = useState<PopupBottom>({ visible: false, type: '' })
  // 右侧弹出层显示状态
  const [popupRight, setPopupRight] = useState<PopupRight>({ visible: false, type: '' })

  // 关闭所有弹出层的封装，方便使用
  const popupClose = () => {
    // 关闭底部弹出层
    setPopupBottom({ visible: false, type: '' })
    // 关闭右侧弹出层
    setPopupRight({ visible: false, type: '' })
  }

  // 准备一个 file 的 ref 用于绑定上传按钮
  const fileRef = useRef<HTMLInputElement>(null)

  // 文件发生变化时触发
  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      // console.log('file', e.target.files[0])
      // 上传文件需要用 FormData
      const file = e.target.files[0]
      // 通过 FormData 传输图片文件
      const fd = new FormData()
      fd.append('photo', file)
      // console.log(fd)
      dispatch(editUserPhoto(fd))
      // 上传成功，关闭弹出层
      popupClose()
    }
  }

  // 修改用户资料的通用事件处理函数，改性别，改昵称，改生日，改简介
  const handleUpdateProfile = async (data: Partial<Profile>) => {
    // 调用编辑用户资料接口
    await dispatch(editUserProfile(data))
    // 成功轻提示
    Toast.show({ content: '更新成功' })
    // 关闭弹出层
    popupClose()
  }

  // 表单：用于绑定授课组件的状态
  const [name, setName] = useState('')
  // 用于绑定个人简介
  const [intro, setIntro] = useState('')
  // 打开右侧弹出层的时候：需要默认显示用户昵称或用户简介
  const popupRightOpen = (type: 'name' | 'intro') => {
    // 设置用户昵称默认值
    if (type === 'name') setName(profile.name)
    // 设置用户简介默认值
    else if (type === 'intro') setIntro(profile.intro)
    // 打开右侧弹出层
    setPopupRight({ visible: true, type: type })
  }

  // 表单提交按钮：内部需要区分提交昵称还是提交简介
  const handleSubmit = () => {
    // 修改昵称
    if (popupRight.type === 'name') handleUpdateProfile({ name })
    // 修改简介
    else if (popupRight.type === 'intro') handleUpdateProfile({ intro })
  }

  // 按回车键提交
  const handleKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
    // console.log(e.key)
    if (e.key === 'Enter') {
      handleSubmit()
    }
  }

  // 日期选择器
  const [pickShow, setPickShow] = useState(false)
  // 点击日期选择器确认按钮时触发
  const handleConfirm = (value: Date) => {
    // 利用 dayjs 格式化日期
    const birthday = dayjs(value).format('YYYY-MM-DD')
    // console.log(birthday)
    // 更新生日信息
    handleUpdateProfile({ birthday })
  }

  // 点击退出按钮
  const handleLogout = () => {
    // Dialog.confirm 弹出确认框
    Dialog.confirm({
      cancelText: '我再想想',
      confirmText: '狠心退出',
      title: '温馨提示',
      content: '是否退出登录？',
      onConfirm: () => {
        // console.log('用户点击了确认，我们需要实现退出登录功能')
        // 清除本地存储的 token
        removeTokenInfo()
        // 清除 redux 中的 token
        dispatch(clearAuth())
        // 跳转到登录页
        history.push('/login')
        // 提示
        Toast.show({ content: '退出成功' })
      },
    })
  }

  return (
    <div className={styles.root}>
      <div className='content'>
        {/* 顶部导航栏 */}
        <NavBar>个人资料</NavBar>

        <div className='wrapper'>
          {/* 列表一：显示头像、昵称、简介 */}
          <List className='profile-list'>
            <List.Item
              arrow
              extra={<img className='avatar' src={profile.photo} alt='' />}
              onClick={() => setPopupBottom({ visible: true, type: 'photo' })}
            >
              头像
            </List.Item>

            <List.Item onClick={() => popupRightOpen('name')} arrow extra={profile.name}>
              昵称
            </List.Item>

            <List.Item
              onClick={() => popupRightOpen('intro')}
              arrow
              extra={<span className='intro'>{profile.intro || '未填写'}</span>}
            >
              简介
            </List.Item>

            <List.Item
              arrow
              extra={profile.gender === 0 ? '男' : '女'}
              onClick={() => setPopupBottom({ visible: true, type: 'gender' })}
            >
              性别
            </List.Item>
            <List.Item arrow extra={profile.birthday} onClick={() => setPickShow(true)}>
              生日
            </List.Item>
          </List>

          {/* 文件选择框，用于头像图片的上传 */}
          <input
            ref={fileRef}
            onChange={(e) => handleFileChange(e)}
            className='avatar-upload'
            type='file'
            accept='.png,.jpg'
          />
        </div>

        {/* 底部栏：退出登录按钮 */}
        <div className='logout'>
          <button className='btn' onClick={handleLogout}>
            退出登录
          </button>
        </div>

        {/* 底部弹出层 */}
        <Popup
          visible={popupBottom.visible}
          position='bottom'
          bodyClassName='popup-bottom-list'
          onMaskClick={() => popupClose()}
        >
          {popupBottom.type === 'photo' ? (
            <>
              <div className='list-item' onClick={() => fileRef.current?.click()}>
                拍照
              </div>
              <div className='list-item' onClick={() => fileRef.current?.click()}>
                本地选择
              </div>
            </>
          ) : (
            <>
              <div className='list-item' onClick={() => handleUpdateProfile({ gender: 0 })}>
                男
              </div>
              <div className='list-item' onClick={() => handleUpdateProfile({ gender: 1 })}>
                女
              </div>
            </>
          )}

          <div className='list-item' onClick={() => popupClose()}>
            取消
          </div>
        </Popup>

        {/* 右侧弹出层 */}
        <Popup
          visible={popupRight.visible}
          position='right'
          bodyClassName='popup-right'
          // 不可见时卸载内容，用于配合加载表单的时候自动获取焦点
          destroyOnClose
        >
          <NavBar
            onBack={() => popupClose()}
            right={
              <span className='submit-btn' onClick={handleSubmit}>
                提交
              </span>
            }
          >
            编辑用户信息
          </NavBar>
          <div className='edit-content'>
            {popupRight.type === 'name' ? (
              <>
                <h3 className='edit-title'>编辑昵称</h3>
                {/* autoFocus 自动获取焦点 */}
                <Input
                  className='edit-input'
                  autoFocus
                  // 受控组件 value + onChange 组合
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                  onKeyUp={(e) => handleKeyUp(e)}
                />
              </>
            ) : (
              <>
                <h3 className='edit-title'>编辑简介</h3>
                <Textarea
                  placeholder='请输入个人简介'
                  autoFocus
                  maxLength={10}
                  value={intro}
                  onChange={(e) => setIntro(e.target.value)}
                />
              </>
            )}
          </div>
        </Popup>

        {/* 日期选择器 */}
        <DatePicker
          visible={pickShow}
          min={new Date('1940-01-01')}
          max={new Date()}
          value={new Date(profile.birthday)}
          onClose={() => setPickShow(false)}
          onConfirm={(e: Date) => handleConfirm(e)}
        />
      </div>
    </div>
  )
}
